﻿using System.Collections.Generic;
using System;
using System.ComponentModel;
using System.Xml;
using System.Xml.Serialization;


namespace KSS.Generator.Configuration
{
    [TypeConverter(typeof(ProjectSettingConverter))]
    public class ProjectSetting : ICloneable, ICustomTypeDescriptor
    {
        public ProjectSetting() { }

        [XmlAttribute]
        public string Name = string.Empty;

        [XmlAttribute]
        public string Description = string.Empty;

        [XmlAttribute]
        public string Namespace = string.Empty;

        [XmlAttribute]
        public string TemplateFolderName = string.Empty;

        [XmlAttribute]
        public string ProjectFolderName = string.Empty;

        [XmlAttribute]
        public string GeneratorName = string.Empty;

        [XmlAttribute]
        public string GeneratorAssembly = string.Empty;

        private List<PropertySetting> _properties;

        [Browsable(false)]
        [XmlElement(ElementName = "Property", Type = typeof(PropertySetting))]
        public List<PropertySetting> Properties
        {
            get
            {
                if (_properties == null)
                {
                    _properties = new List<PropertySetting>();
                }

                return _properties;
            }
            set
            {
                _properties = value;
            }
        }

        public override string ToString()
        {
            return Name;
        }

        /// <summary>
        /// Get property setting in a project
        /// </summary>
        /// <param name="project"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public PropertySetting GetProperty(string propertyName)
        {
            PropertySetting property = Properties.Find(
                    delegate(PropertySetting p)
                    {
                        return (p.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase));
                    });

            return property;
        }

        /// <summary>
        /// Set value for a specific property
        /// </summary>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        public void SetPropertyValue(string propertyName, string value)
        {
            PropertySetting property = GetProperty(propertyName);

            if (property != null)
            {
                property.Value = value;
            }
        }

        /// <summary>
        /// Get a property value
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public string GetPropertyValue(string propertyName)
        {
            PropertySetting property = GetProperty(propertyName);

            if (property != null)
            {
                return property.Value;
            }

            return null;
        }

        #region ICloneable Members

        public object Clone()
        {
            ProjectSetting setting = new ProjectSetting();
            setting.Name = Name;
            setting.Description = Description;
            setting.Namespace = Namespace;
            setting.TemplateFolderName = TemplateFolderName;
            setting.ProjectFolderName = ProjectFolderName;

            setting.Properties = new List<PropertySetting>();
            foreach (PropertySetting property in Properties)
            {
                setting.Properties.Add((PropertySetting)property.Clone());
            }

            return setting;
        }

        #endregion

        #region ICustomTypeDescriptor Members

        public AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(this, true);
        }

        public string GetClassName()
        {
            return TypeDescriptor.GetClassName(this, true);
        }

        public string GetComponentName()
        {
            return TypeDescriptor.GetComponentName(this, true);
        }

        public TypeConverter GetConverter()
        {
            return TypeDescriptor.GetConverter(this, true);
        }

        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(this, true);
        }

        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this, true);
        }

        public object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(this, editorBaseType, true);
        }

        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            return TypeDescriptor.GetEvents(this, attributes, true);
        }

        public EventDescriptorCollection GetEvents()
        {
            return TypeDescriptor.GetEvents(this, true);
        }

        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            return this;
        }

        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            return GetProperties();
        }

        public PropertyDescriptorCollection GetProperties()
        {
            PropertyDescriptorCollection propertyDescriptors = new PropertyDescriptorCollection(null);

            PropertySettingPropertyDescriptor descriptor = null;
            foreach (PropertySetting property in Properties)
            {
                descriptor = new PropertySettingPropertyDescriptor(property);                
                propertyDescriptors.Add(descriptor);
            }

            return propertyDescriptors;
        }

        #endregion
    }
}
